package service

import (
	"errors"
	"reflect"
	"strings"
	"sync"

	"sieve_admin_server_userpass/pkg/json"
)

var (
	msgHandlers = map[string]func(*UserConn, []byte) interface{}{}
	msgLock     = sync.Mutex{}
)

type UserConn struct {
	Id         int64
	Uid        int
	RemoteAddr string
	Login      struct {
		Pf    string
		Ver   string
		LogId int64
	}
}

type MsgHandler interface {
	Handle(*UserConn) interface{}
}

type api_IM_MSG struct {
	Name string
	Data string
	Conn *UserConn
}

func (a *api_IM_MSG) Handle(caller string) interface{} {
	h, ok := msgHandlers[a.Name]
	if !ok {
		return errors.New("msg not found: " + a.Name)
	}
	return h(a.Conn, []byte(a.Data))
}

func init() {
	AddApiHandler(&api_IM_MSG{})
}

func AddMsgHandler(msg MsgHandler) error {
	msgLock.Lock()
	defer msgLock.Unlock()

	t := reflect.TypeOf(msg).Elem()
	name := t.Name()
	if !strings.HasPrefix(name, "msg_") {
		return errors.New("have to start with msg_")
	}
	name = name[4:]
	msgHandlers[name] = func(c *UserConn, b []byte) interface{} {
		v := reflect.New(t).Interface()
		if err := json.Unmarshal(b, &v); err != nil {
			return err
		}
		return v.(MsgHandler).Handle(c)
	}
	return addMsgHandler(name)
}
